package cn.edu.cug.cs.gtl.plugins.catalog.tree;

import cn.edu.cug.cs.gtl.apis.ui.AbstractApplication;
import cn.edu.cug.cs.gtl.apis.ui.actions.AbstractAction;
import cn.edu.cug.cs.gtl.apis.ui.datake.DatakeApp;
import cn.edu.cug.cs.gtl.apis.ui.datake.DatakeFrame;
import cn.edu.cug.cs.gtl.apis.ui.datake.catalogtree.CatalogTree;
import cn.edu.cug.cs.gtl.apis.ui.datake.catalogtree.JTreeTools;
import cn.edu.cug.cs.gtl.apis.ui.tree.TreeNodeData;
import cn.edu.cug.cs.gtl.plugins.catalog.utils.HdfsFileUtils;
import cn.edu.cug.cs.gtl.protos.*;
import cn.edu.cug.cs.gtl.utils.impl.DataItemManagerImpl;
import cn.edu.cug.cs.gtl.utils.postgresql.DataGroupManager4Postgresql;

import javax.swing.*;
import javax.swing.filechooser.FileSystemView;
import javax.swing.tree.*;
import javax.swing.tree.TreeNode;
import java.awt.event.ActionEvent;
import java.io.File;
import java.sql.SQLException;
import java.util.Locale;
import java.util.ResourceBundle;
import java.util.UUID;

public class AddNewItemAction extends AbstractAction {
    @Override
    public void initialize(AbstractApplication theApp) {
        this.theApp = theApp;
        ResourceBundle resourceBundle = ResourceBundle.getBundle("catalog-resource", Locale.getDefault());

        name = resourceBundle.getString("popupmenu.catalog.tree.add_new_item");
        menuItem.setText(name);
        menuItem.addActionListener(this);
        ((CatalogTree) (getDatakeFrame().getCatalogPanel().getTreeComponent())).getGroupNodePopupMenu().add(menuItem);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        //弹出文件对话框选择文件
//        JFileChooser fileChooser = new JFileChooser(FileSystemView.getFileSystemView());  //参数为文件对话框打开的默认路径，这里设置为文档
        JFileChooser fileChooser = new JFileChooser(FileSystemView.getFileSystemView().getHomeDirectory());
        fileChooser.setDialogTitle("选择文件作为数据项");
        fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);    //设置文件选择模式，可以选择文件或目录
        int returnValue = fileChooser.showOpenDialog(null);   //显示文件对话框
        // 处理用户的选择
        if (returnValue == JFileChooser.APPROVE_OPTION) {
            try {
                File selectedFile = fileChooser.getSelectedFile();
                String localFilePath = selectedFile.getAbsolutePath();    // 获取选择的本地文件路径
                String fileAlias = selectedFile.getName(); // 获取选择的本地文件名
                String extension="";    //文件名后缀默认为空
                // 判断文件名是否包含后缀名
                if (fileAlias.contains(".")) {
                    extension = fileAlias.substring(fileAlias.lastIndexOf(".")); //截取原始文件名的后缀
                }
                String fileName = UUID.randomUUID().toString() + extension; //构造新文件名称，uuid方式
                String hdfsPath = "hdfs://202.114.198.141:8020/data/lake/";    // 设置上传的hdfs文件路径

                String hdfsUri = "hdfs://202.114.198.141:8020/";

//                Configuration configuration = new Configuration();
//                configuration.set("dfs.client.use.datanode.hostname", "true");
//                FileSystem fileSystem = FileSystem.get(new URI("hdfs://202.114.198.141:8020/"), configuration, "root");
//
//                // 检查HDFS路径是否存在
//                Path hdfsDestPath = new Path(hdfsPath);
//                if (fileSystem.exists(hdfsDestPath)) {
//                    System.err.println("HDFS路径已经存在");
//                    return;
//                }
//                fileSystem.copyFromLocalFile(new Path(localFilePath), hdfsDestPath); //上传本地文件到hdfs，需要本地配置host文件
//                boolean uploadSuccess = fileSystem.exists(hdfsDestPath); // 上传本地文件到hdfs并检查是否成功

                //在JTree目录树中显示文件夹目录结构
                CatalogTree tree = (CatalogTree) getDatakeFrame().getCatalogPanel().getTreeComponent();
                DefaultMutableTreeNode selectNode = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();
                DataGroup dataGroup = (DataGroup) ((TreeNodeData) (selectNode.getUserObject())).getRefObject();

                // 从选中节点向上遍历到根节点，构建路径
                StringBuilder pathBuilder = new StringBuilder();
                buildPathFromRoot(selectNode, pathBuilder);

                // 构建完整的HDFS路径
                String fullHdfsPath = hdfsPath + pathBuilder + "/" + fileName + "/";

                boolean uploadSuccess = HdfsFileUtils.uploadFile(dataGroup.getName(), hdfsUri, localFilePath, fullHdfsPath);
                if (uploadSuccess) {
                    FileKey fileKey = FileKey.newBuilder().setUrl(fullHdfsPath).setFileName(fileName).setFileAlias(fileAlias).build();
                    DataKey dataKey = DataKey.newBuilder().setFileKey(fileKey).build();

                    DataItem newItem = DataItem.newBuilder().setName(fileName).setAlias(fileAlias).setFormat(extension).setKey(dataKey).build();
                    DefaultMutableTreeNode newNode = new DefaultMutableTreeNode(new TreeNodeData(newItem, newItem.getAlias(), true), false);

                    DefaultTreeModel treeModel = (DefaultTreeModel) tree.getModel();
                    treeModel.insertNodeInto(newNode, selectNode, selectNode.getChildCount());

                    TreeNode[] nodes = treeModel.getPathToRoot(newNode);
                    tree.scrollPathToVisible(new TreePath(nodes));
                } else JOptionPane.showMessageDialog(null, "上传失败", "错误", JOptionPane.ERROR_MESSAGE);
            } catch (Exception exception) {
                exception.printStackTrace();
            }
        } else System.err.println("用户取消了选择");
    }

    // 辅助方法，用于从根节点到选中节点构建路径
    private void buildPathFromRoot(DefaultMutableTreeNode node, StringBuilder pathBuilder) {
        // 向上遍历到根节点
        while (node != null&&node.getParent()!=null) {
            // 确保StringBuilder以正确的分隔符开始
            if (pathBuilder.length() > 0) {
                pathBuilder.insert(0, "/");
            }

            Object userObject = ((TreeNodeData) node.getUserObject()).getRefObject();
            if (userObject instanceof DataCatalog) {
                // 假设TreeNodeData的getRefObject方法返回节点名称
                String nodeName = ((DataCatalog) userObject).getName().toString();
                pathBuilder.insert(0, nodeName); // 将节点名称添加到路径的前面
            } else if (userObject instanceof DataGroup) {
                String nodeName = ((DataGroup) userObject).getName().toString();
                pathBuilder.insert(0, nodeName);
            } else if (userObject instanceof DataItem) {
                String nodeName = ((DataItem) userObject).getName().toString();
                pathBuilder.insert(0, nodeName);
            } else {
                throw new RuntimeException("未知的节点类型.");
            }
            node = (DefaultMutableTreeNode) node.getParent(); // 移动到父节点
        }
    }

    private void createTreeNodeAddToTree(String fileName, String fileAlias, String extension, DataKey dataKey) throws SQLException {
        CatalogTree tree = (CatalogTree) getDatakeFrame().getCatalogPanel().getTreeComponent();
        DefaultMutableTreeNode selectNode = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();
        DataGroup dataGroup = (DataGroup) ((TreeNodeData) (selectNode.getUserObject())).getRefObject();
        DataItem newItem = DataItem.newBuilder().setName(fileName).setAlias(fileAlias).setFormat(extension).setKey(dataKey).build();
        new DataItemManagerImpl().insertDataItem(newItem);
        boolean ret = new DataGroupManager4Postgresql().addDataItemToGroup(dataGroup.getName(), newItem.getName());
        if (!ret)
            JOptionPane.showMessageDialog(null, "插入失败，可能dataItem表中不存在名称为" + newItem.getName() + "的对象", "错误", JOptionPane.ERROR_MESSAGE);

        DefaultMutableTreeNode newNode = new DefaultMutableTreeNode(new TreeNodeData(newItem, newItem.getAlias(), true), false);

        DefaultTreeModel treeModel = (DefaultTreeModel) tree.getModel();
        treeModel.insertNodeInto(newNode, selectNode, selectNode.getChildCount());

        TreeNode[] nodes = treeModel.getPathToRoot(newNode);
        tree.scrollPathToVisible(new TreePath(nodes));
    }

    public DatakeFrame getDatakeFrame() {
        return (DatakeFrame) (((DatakeApp)theApp).getMainFrame());
    }
}
